from django.core.exceptions import ValidationError


import json
import random
from web import models
from utils import encrypt
from django import forms
from web.forms.bootstrap import BootstrapForm
from django.conf import settings
from utils.alicloud.sms import send_sms
from django_redis import get_redis_connection
from django.core.validators import RegexValidator


class RegisterModelForm(BootstrapForm, forms.ModelForm):

    username = forms.CharField(
        label='用户名',
        required=True,
        error_messages={'required': '用户名不能为空'}
    )
    email = forms.EmailField(
        label='邮箱',
        required=True,
        error_messages={'required': '邮箱不能为空'}
    )
    phone_regex = r'^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$'
    mobile_phone = forms.CharField(
        label='手机号',
        validators=[RegexValidator(phone_regex, '手机号格式错误')],
        required=True,
        error_messages={'required': '手机号不能为空'}
    )
    password = forms.CharField(
        label='密码',
        widget=forms.PasswordInput(),
        required=True,
        min_length=8,
        max_length=32,
        error_messages={
            'required': '密码不能为空',
            'min_length': '密码长度不能小于8个字符',
            'max_length': '密码长度不能大于32个字符',
        }
    )
    confirm_password = forms.CharField(
        label='确认密码',
        widget=forms.PasswordInput(),
        required=True,
        error_messages={'required': '请确认密码'}
    )
    code = forms.CharField(
        label='验证码',
        required=True,
        error_messages={'required': '请输入验证码'}
    )

    class Meta:
        model = models.UserInfo
        fields = ['username', 'email', 'password', 'confirm_password', 'mobile_phone', 'code']

    # def __init__(self, *args, **kwargs):
    #     super().__init__(*args, **kwargs)
    #     for name, field in self.fields.items():
    #         field.widget.attrs['class'] = 'form-control'
    #         field.widget.attrs['placeholder'] = '请输入' + field.label

    def clean_username(self):
        username = self.cleaned_data['username']
        exists = models.UserInfo.objects.filter(username=username).exists()
        if exists:
            self.add_error('username', '用户名已存在')
            # raise ValidationError('用户名已存在')
        return username

    def clean_email(self):
        email = self.cleaned_data['email']
        exists = models.UserInfo.objects.filter(email=email).exists()
        if exists:
            self.add_error('email', '邮箱已存在')
            # raise ValidationError('邮箱已存在')
        return email

    def clean_password(self):
        password = self.cleaned_data['password']
        # 将password加密并返回
        return encrypt.md5(password)

    def clean_confirm_password(self):
        # password = self.cleaned_data['password']
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data['confirm_password']
        if not password:
            return confirm_password
        confirm_password = encrypt.md5(confirm_password)
        if password != confirm_password:
            self.add_error('confirm_password', '两次密码不相同')
            # raise ValidationError('两次密码不相同')
        return confirm_password

    def clean_mobile_phone(self):
        mobile_phone = self.cleaned_data['mobile_phone']
        exists = models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if exists:
            self.add_error('mobile_phone', '手机号已存在')
            # raise ValidationError('手机号已存在')
        return mobile_phone

    def clean_code(self):
        code = self.cleaned_data['code']
        # mobile_phone = self.cleaned_data['mobile_phone']
        mobile_phone = self.cleaned_data.get('mobile_phone')
        if not mobile_phone:
            return code
        conn = get_redis_connection('default')
        gt_code = conn.get(mobile_phone)
        if not gt_code:
            self.add_error('code', '验证码失效获未发送，请重新获取')
            # raise ValidationError('验证码失效获未发送，请重新获取')
        if gt_code != str(code).encode():
            self.add_error('code', '验证码不正确')
            # raise ValidationError('验证码不正确')
        return code


class LoginSmsForm(BootstrapForm, forms.Form):
    phone_regex = r'^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$'
    mobile_phone = forms.CharField(
        label='手机号',
        validators=[RegexValidator(phone_regex, '手机号格式错误')],
        required=True,
        error_messages={'required': '手机号不能为空'}
    )
    code = forms.CharField(
        label='验证码',
        required=True,
        error_messages={'required': '请输入验证码'}
    )

    def clean_mobile_phone(self):
        mobile_phone = self.cleaned_data['mobile_phone']
        exists = models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if not exists:
            self.add_error('mobile_phone', '手机号未注册')
        return mobile_phone

    def clean_code(self):
        code = self.cleaned_data['code']
        mobile_phone = self.cleaned_data.get('mobile_phone')
        # if not mobile_phone:
        #     return code
        conn = get_redis_connection('default')
        gt_code = conn.get(mobile_phone)
        if not gt_code:
            self.add_error('code', '验证码失效获未发送，请重新获取')
        if gt_code != str(code).encode():
            self.add_error('code', '验证码不正确')
        return code


    # def __init__(self, *args, **kwargs):
    #     super().__init__(*args, **kwargs)
    #     for name, field in self.fields.items():
    #         field.widget.attrs['class'] = 'form-control'
    #         field.widget.attrs['placeholder'] = '请输入' + field.label


class LoginForm(BootstrapForm, forms.Form):

    username = forms.CharField(
        label='邮箱或手机号',
        required=True,
        error_messages={'required': '用户名不能为空'}
    )
    password = forms.CharField(
        label='密码',
        widget=forms.PasswordInput(render_value=True),
        required=True,
        error_messages={'required': '密码不能为空'}
    )
    code = forms.CharField(
        label='验证码',
        required=True,
        error_messages={'required': '请输入验证码'}
    )

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request

    def clean_password(self):
        password = self.cleaned_data['password']
        # 将password加密并返回
        return encrypt.md5(password)

    def clean_code(self):
        code = self.cleaned_data['code']
        session_code = self.request.session.get('image_code')

        if not session_code:
            self.add_error('code', '验证码已过期，请点击图片重新获取')

        if code.strip().upper() != session_code.strip().upper():
            self.add_error('code', '验证码输入错误')

        return code



